#include "inc.h"
#define BUFFER_SIZE 1024

void log(const char *fmt, ...) {
  char buf[BUFFER_SIZE+1] = { 0 };
  va_list va;
  va_start(va, fmt);
  vsprintf(buf, fmt, va);
  va_end(va);
  log_screen(buf);
  log_file(buf);
}
void log_screen(const char *fmt, ...) {
  char buf[BUFFER_SIZE+1] = { 0 };
  va_list va;
  va_start(va, fmt);
  vsprintf(buf, fmt, va);
  va_end(va);
  printf(buf);
}
void log_file(const char *fmt, ...) {
  va_list va;
  FILE *filp = fopen("winvnc_proxy.log", "a+");
	if (filp) {
		va_start(va, fmt);
		vfprintf(filp, fmt, va);
		va_end(va);
		fclose(filp);
	}
}
void log_out(std::string &out, const char *fmt, ...) {
	char buf[BUFFER_SIZE+1] = { 0 };
  va_list va;
  va_start(va, fmt);
  vsprintf(buf, fmt, va);
  va_end(va);
  out.append(buf);
}

static bool is_visible(const char c) {
  if (c < 0x20) return false;
  if (c > 0x7F) return false;
  return true;
}

void show_hex(const char *data, int len, int stride) {
  if (!data || len <= 0) return;
  if (stride <= 0) stride = 8;
  char *ch = new char[stride];
  if (!ch) return;
  std::string buf;
  for (int j = 0; j < stride; ++j) ch[j] = 0;
  int c = -1;
  for (int i = 0; i < len; ++i) {
    c = i%stride;
    ch[c] = data[i];
    if (c == stride -1 || i == len - 1) {
      // show
      for (int j = 0; j <= c; ++j)
        log_out(buf, "%02X ", (unsigned char)ch[j]);
      for (int j = stride - 1 - c; j > 0; --j)
        log_out(buf, "   ");
      log_out(buf, "| ");
      for (int j = 0; j < stride; ++j) {
        if (is_visible(ch[j])) log_out(buf, "%c", ch[j]);
        else log_out(buf, ".");
      }
      log_out(buf, "\n");
      for (int j = 0; j < stride; ++j) ch[j] = 0;
    }
  }
  log_out(buf, "\n");
  log(buf.c_str());
  delete ch;
}